#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "core/global.h"
#include "server/Room.h"
#include "client/ClientPlayer.h"

#include <QDebug>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    room = new Room(this);
    client_dialog = new ClientDialog(this);
    server_dialog = new ServerDialog(this);
    server_info = new ServerInfo(this);
    config_dialog = new ConfigDialog(this);
    ui->chatLog->setReadOnly(true);

    ui->endButton->setEnabled(false);

    connect(ui->actionStartClient, SIGNAL(triggered()), client_dialog, SLOT(show()));
    connect(ui->actionStartServer, SIGNAL(triggered()), server_dialog, SLOT(show()));
    connect(ui->actionExit, SIGNAL(triggered()), qApp, SLOT(quit()));
    connect(ui->actionConfig, SIGNAL(triggered()), config_dialog, SLOT(show()));
    connect(ui->chatEdit, SIGNAL(editingFinished()), this, SLOT(sendChatMessage()));
    connect(ui->sendButton, SIGNAL(clicked()), ui->chatEdit, SIGNAL(editingFinished()));
    connect(ui->hostedButton, SIGNAL(clicked()), this, SLOT(setHosted()));
    connect(ui->endButton, SIGNAL(clicked()), this, SLOT(roundEnd()));

    connect(server_dialog, SIGNAL(serverConfig(qint16,QString,int)), room, SLOT(setConfig(qint16,QString,int)));
    connect(server_dialog, SIGNAL(accepted()), server_info, SLOT(show()));

    connect(Self, SIGNAL(onConnected()), server_info, SLOT(hide()));
    connect(Self, SIGNAL(onChat(QString, QString)), this, SLOT(showChatMessage(QString,QString)));
    connect(Self, SIGNAL(onNewPlayer(int,QString)), ui->boardView, SLOT(addPlayer(int,QString)));
    connect(Self, SIGNAL(onNewPlayer(int,QString)), this, SLOT(announceNewPlayer(int,QString)));
    connect(Self, SIGNAL(onUpdatePlayer(int,QString)), ui->boardView, SLOT(setPlayerProperty(int,QString)));
    connect(Self, SIGNAL(occurError(QString)), this, SLOT(showWarning(QString)));
    connect(Self, SIGNAL(onMovePiece(int,int,int)), ui->boardView, SLOT(movePiece(int,int,int)));

    connect(room, SIGNAL(serverNameChanged(QString)), server_info, SLOT(setServerName(QString)));
    connect(room, SIGNAL(serverPortChanged(ushort)), server_info, SLOT(setServerPort(ushort)));
    connect(room, SIGNAL(playerNumChanged(int)), server_info, SLOT(setPlayerNum(int)));
    connect(room, SIGNAL(occurError(QString)), this, SLOT(showWarning(QString)));

    connect(ui->boardView, SIGNAL(roundChanged(bool)), ui->endButton, SLOT(setEnabled(bool)));

    if(Config.contains("window/Position")){
        move(Config.value("window/Position").toPoint());
    }
    if(Config.contains("window/Size")){
        resize(Config.value("window/Size").toSize());
    }
    if(Config.contains("window/State")){
        setWindowState((Qt::WindowStates) Config.value("window/State").toInt());
    }
}

MainWindow::~MainWindow(){
    if(!isMaximized()){
        Config.setValue("window/Position", pos());
        Config.setValue("window/Size", size());
    }
    Config.setValue("window/State", (int) windowState());

    delete ui;
}

void MainWindow::setStatusBarText(QString text){
    ui->statusBar->showMessage(text);
}

void MainWindow::showWarning(const QString &message){
    QMessageBox::warning(this, tr("Warning Message"), message);
}

void MainWindow::showInfo(const QString &title, const QString &content){
    QMessageBox::information(this, title, content);
}


void MainWindow::showChatMessage(const QString &player_name, const QString &msg){
    if(player_name.isNull() || player_name.isEmpty()){
        ui->chatLog->append(QString("%1").arg(msg));
    }else{
        ui->chatLog->append(QString("%1:%2").arg(player_name).arg(msg));
    }
}

void MainWindow::sendChatMessage(){
    if(!ui->chatEdit->text().isEmpty()){
        Self->chat(ui->chatEdit->text());
        ui->chatEdit->clear();
    }
}

void MainWindow::announceNewPlayer(int, const QString &name){
    ui->chatLog->append(name + tr(" entered this room."));
}

void MainWindow::on_actionStartGame_triggered(){
    ushort port = Config.value("game/serverPort").toUInt();
    QString server_name = Config.value("game/serverName").toString();
    int player_num = Config.value("game/playerNum").toInt();
    room->setConfig(port, server_name, player_num);

    QString user_name = Config.value("game/userName").toString();
    Self->setPlayerName(user_name);
    Self->connectToServer("127.0.0.1", port);
}

void MainWindow::on_actionFullScreen_triggered(){
    if(isFullScreen()){
        showMaximized();
    }else{
        showFullScreen();
    }
}

void MainWindow::on_actionServerInfo_triggered(){
    if(!room->isListening()){
        showWarning(tr("The server has not been started."));
    }else{
        server_info->show();
    }
}

void MainWindow::on_actionReady_triggered(){
    Self->setProperty("is_ready", true);
    Self->notifyProperty("is_ready");
}

void MainWindow::setHosted(){
    bool hosted = !Self->isHosted();
    Self->setHosted(hosted);
    if(Self->isHosted()){
        ui->hostedButton->setText(tr("Unhosted"));
    }else{
        ui->hostedButton->setText(tr("Hosted"));
    }
}

void MainWindow::roundEnd(){
    Self->setPhase(Player::End);
    Self->notifyProperty("phase");
    ui->endButton->setEnabled(false);
}
